package com.ruoyi.business.controller;

import java.io.InputStream;
import java.net.URLEncoder;
import java.util.*;

import cn.afterturn.easypoi.word.WordExportUtil;
import com.ruoyi.business.domain.*;
import com.ruoyi.business.domain.dto.FinishRecordInfo;
import com.ruoyi.business.domain.vo.CollectItemWithDataVO;
import com.ruoyi.business.rabbitmq.AcquisitionProtocolConstants;
import com.ruoyi.business.rabbitmq.listener.SignalListener;
import com.ruoyi.business.rabbitmq.po.SignalInfo;
import com.ruoyi.business.rabbitmq.po.TaskInfo;
import com.ruoyi.business.rabbitmq.publisher.Publisher;
import com.ruoyi.business.service.*;
import com.ruoyi.business.service.impl.AsherSocketService;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.quartz.service.MediaServerService;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.beans.BeanUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;

import javax.servlet.http.HttpServletResponse;

/**
 * 实验方案Controller
 * 
 * @author asher
 * @date 2021-10-28
 */
@RestController
@RequestMapping("/business/scheme")
public class BusExperimentSchemeController extends BaseController
{
    @Autowired
    private IBusExperimentSchemeService busExperimentSchemeService;

    @Autowired
    private Publisher publisher;

    @Autowired
    private SignalListener signalListener;

    @Autowired
    private IBusCollectionItemService busCollectionItemService;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private ICollectedDataService collectedDataService;

    @Autowired
    private IVideoChannelsService videoChannelsService;

    @Autowired
    private MediaServerService mediaServerService;

    @Autowired
    private IRecordFileService recordFileService;

    @Autowired
    private IAsherSocketService asherSocketService;

    public static final String CUSTOM_PATH_PREV = "E:\\soft\\ffmpeg-record\\CollectItemId";

    /**
     * 查询实验方案列表
     */
    @PreAuthorize("@ss.hasPermi('business:scheme:list')")
    @GetMapping("/list")
    public TableDataInfo list(BusExperimentScheme busExperimentScheme)
    {
        startPage();
        List<BusExperimentScheme> list = busExperimentSchemeService.selectBusExperimentSchemeList(busExperimentScheme);
        return getDataTable(list);
    }

    /**
     * 导出实验方案列表
     */
    @PreAuthorize("@ss.hasPermi('business:scheme:export')")
    @Log(title = "实验方案", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    public AjaxResult export(BusExperimentScheme busExperimentScheme)
    {
        List<BusExperimentScheme> list = busExperimentSchemeService.selectBusExperimentSchemeList(busExperimentScheme);
        ExcelUtil<BusExperimentScheme> util = new ExcelUtil<BusExperimentScheme>(BusExperimentScheme.class);
        return util.exportExcel(list, "实验方案数据");
    }

    /**
     * 获取实验方案详细信息
     */
    @PreAuthorize("@ss.hasPermi('business:scheme:query')")
    @GetMapping(value = "/{schemeId}")
    public AjaxResult getInfo(@PathVariable("schemeId") Long schemeId)
    {
        return AjaxResult.success(busExperimentSchemeService.selectBusExperimentSchemeBySchemeId(schemeId));
    }

    /**
     * 新增实验方案
     */
    @PreAuthorize("@ss.hasPermi('business:scheme:add')")
    @Log(title = "实验方案", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody BusExperimentScheme busExperimentScheme)
    {
        return toAjax(busExperimentSchemeService.insertBusExperimentScheme(busExperimentScheme), busExperimentScheme);
    }

    /**
     * 修改实验方案
     */
    @PreAuthorize("@ss.hasPermi('business:scheme:edit')")
    @Log(title = "实验方案", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody BusExperimentScheme busExperimentScheme)
    {
        return toAjax(busExperimentSchemeService.updateBusExperimentScheme(busExperimentScheme));
    }

    /**
     * 删除实验方案
     */
    @PreAuthorize("@ss.hasPermi('business:scheme:remove')")
    @Log(title = "实验方案", businessType = BusinessType.DELETE)
	@DeleteMapping("/{schemeIds}")
    public AjaxResult remove(@PathVariable Long[] schemeIds)
    {
        return toAjax(busExperimentSchemeService.deleteBusExperimentSchemeBySchemeIds(schemeIds));
    }

    /**
     * 导出word形式
     * @param response
     */
    @GetMapping("/exportWord")
    public void exportWord(HttpServletResponse response, Long schemeId){

        try {
            BusExperimentScheme busExperimentScheme = busExperimentSchemeService.selectBusExperimentSchemeBySchemeId(schemeId);
            if (busExperimentScheme == null) {
                throw new Exception("实验报告不存在");
            }
            Map<String,Object> map = new HashMap<>();
            map.put("schemeName", busExperimentScheme.getSchemeName());
            map.put("schemePurpose", busExperimentScheme.getSchemePurpose());
            map.put("schemeContent", busExperimentScheme.getSchemeContent());
            map.put("startTime", DateUtils.parseDateToStr("yyyy年MM月dd日 HH时mm分ss秒 ", busExperimentScheme.getStartTime()));
            map.put("endTime", DateUtils.parseDateToStr("yyyy年MM月dd日 HH时mm分ss秒 ", busExperimentScheme.getEndTime()));
            map.put("operator", busExperimentScheme.getOperator());
            response.setContentType("application/msword");
            response.setCharacterEncoding("utf-8");
            String fileName = URLEncoder.encode(UUID.randomUUID().toString(),"UTF-8" );
            response.setHeader("Content-disposition","attachment;filename="+fileName+".docx" );
            InputStream resourceAsStream = this.getClass().getResourceAsStream("templates/scheme_report.docx");
            XWPFDocument doc = WordExportUtil.exportWord07("templates/scheme_report.docx",map);
            doc.write(response.getOutputStream());
        } catch (Exception e) {
            e.printStackTrace();
        }
        //WordUtil.exportWord("templates/demo.docx","D:/" ,"生成文件.docx" ,map );
    }

    @GetMapping("/startCollect")
    public AjaxResult startCollect(String schemeId) {
        if (!StringUtils.isNotEmpty(schemeId)) {
            return AjaxResult.error();
        }
        BusExperimentScheme busExperimentScheme = (BusExperimentScheme)redisCache.getCacheObject("COLLECTING_SCHEME");
        if (busExperimentScheme != null) {
            return AjaxResult.error("当前有实验方案正在采集数据...");
        }
        try {
            // 检测有没有采集项
            BusCollectionItem busCollectionItem = new BusCollectionItem();
            busCollectionItem.setSchemeId(Long.valueOf(schemeId));
            List<BusCollectionItem> busCollectionItems = busCollectionItemService.selectBusCollectionItemList(busCollectionItem);
            if (busCollectionItems.size() == 0) {
                return AjaxResult.error("当前实验方案没有采集项，请核对");
            }
            // 发送采集卡采集信号
            signalListener.initCache();
            SignalInfo signalInfo = new SignalInfo();
            signalInfo.setCmd(AcquisitionProtocolConstants.DISPATCH_SIGNAL_START);
            signalInfo.setDelay(0);
            signalInfo.setDispatchTime(DateUtils.getNowDate());

            // 查询物理量采集项
            busCollectionItem.setType("0");
            busCollectionItems = busCollectionItemService.selectBusCollectionItemList(busCollectionItem);
            List<TaskInfo> taskInfos = new ArrayList();
            if (busCollectionItems != null && busCollectionItems.size() > 0) {
                String taskName = UUID.randomUUID().toString().replaceAll("-", "");
                busCollectionItems.forEach(item -> {
                    TaskInfo taskInfo = new TaskInfo();
                    taskInfo.setCollectItemId(item.getCollectionItemId().toString());
                    taskInfo.setCardId(item.getAcquisitionCardId().toString());
                    taskInfo.setCardCode(item.getCardCode());
                    taskInfo.setChannelId(item.getChannelId().toString());
                    taskInfo.setChannelCode(item.getChannelCode());
                    taskInfo.setTaskName(taskName);
                    taskInfo.setMaxRange(item.getMaxRange());
                    taskInfo.setMinRange(item.getMinRange());
                    taskInfo.setRate(Double.valueOf(item.getFrequency()));
                    taskInfo.setSamplesPerChannel(Double.valueOf(item.getSamplesPerChannel()));
                    taskInfo.setDeviceCode(item.getDeviceCode());
                    taskInfos.add(taskInfo);
                });
                signalInfo.setTasks(taskInfos);
                publisher.publishSignal(AcquisitionProtocolConstants.SIGNAL_EXCHANGER_NAME, signalInfo);
            }

            // 查询视频采集项
            busCollectionItem.setType("1");
            List<BusCollectionItem> videoCollectionItems = busCollectionItemService.selectBusCollectionItemList(busCollectionItem);
            for (BusCollectionItem item : videoCollectionItems) {
                VideoChannels videoChannels = videoChannelsService.selectVideoChannelsById(item.getChannelId());
                mediaServerService.startRecord(videoChannels.getMediaserverid(), videoChannels.getMainid(), getCustomPath(videoChannels, item.getCollectionItemId().toString()));
            }

            // 查询压力盒采集项
            busCollectionItem.setType("2");
            List<BusCollectionItem> stationCollectionItems = busCollectionItemService.selectBusCollectionItemList(busCollectionItem);
            AsherSocketService.socketCollect = true;
            asherSocketService.startCollectStationData(stationCollectionItems);


            // 处理状态
            redisCache.setCacheObject("COLLECTING_SCHEME", busExperimentSchemeService.selectBusExperimentSchemeBySchemeId(Long.valueOf(schemeId)));
            redisCache.setCacheObject("COLLECTING_STATUS", true);
        } catch (Exception e) {
            System.out.println(e);
            return AjaxResult.error();
        }
        return AjaxResult.success();
    }

    @GetMapping("/stopCollect")
    public AjaxResult stopCollect() {
        try {
            // 发送停止采集信号
            SignalInfo signalInfo = new SignalInfo();
            signalInfo.setCmd(AcquisitionProtocolConstants.DISPATCH_SIGNAL_STOP);
            signalInfo.setDelay(0);
            signalInfo.setDispatchTime(DateUtils.getNowDate());
            publisher.publishSignal(AcquisitionProtocolConstants.SIGNAL_EXCHANGER_NAME, signalInfo);
            signalListener.initCacheTimer();

            // 发送停止录制信号
            BusCollectionItem busCollectionItem = new BusCollectionItem();
            busCollectionItem.setType("1");
            List<BusCollectionItem> videoCollectionItems = busCollectionItemService.selectBusCollectionItemList(busCollectionItem);
            for (BusCollectionItem item : videoCollectionItems) {
                VideoChannels videoChannels = videoChannelsService.selectVideoChannelsById(item.getChannelId());
                mediaServerService.stopRecord(videoChannels.getMediaserverid(), videoChannels.getMainid());
            }

            AsherSocketService.socketCollect = false;
            // 处理状态
            redisCache.deleteObject("COLLECTING_SCHEME");
            redisCache.setCacheObject("COLLECTING_STATUS", false);
        } catch (Exception e) {
            System.out.println(e);
            return AjaxResult.error();
        }
        return AjaxResult.success();
    }

    @GetMapping("/getCollectingStatus")
    public AjaxResult getCollectingStatus() {
        HashMap<String, Object> res = new HashMap<>();
        try {
            BusExperimentScheme busExperimentScheme = (BusExperimentScheme)redisCache.getCacheObject("COLLECTING_SCHEME");
            Boolean collectingStatus = (Boolean)redisCache.getCacheObject("COLLECTING_STATUS");
            Boolean insertDbStatus = (Boolean)redisCache.getCacheObject("INSERT_DB_STATUS");
            res.put("COLLECTING_STATUS", collectingStatus);
            res.put("INSERT_DB_STATUS", insertDbStatus);
            res.put("COLLECTING_SCHEME", busExperimentScheme);
        } catch (Exception e) {
            System.out.println(e);
            return AjaxResult.error();
        }
        return AjaxResult.success(res);
    }

    @GetMapping("/getSchemeData")
    public AjaxResult getSchemeData(Long schemeId, Integer size) {
        if (schemeId == null) {
            return AjaxResult.error("实验方案ID不能为空");
        }
        if (size == null) {
            size = 400;
        }
        BusCollectionItem busCollectionItem = new BusCollectionItem();
        busCollectionItem.setSchemeId(schemeId);
        busCollectionItem.setType("0");
        // 处理物理采集
        List<BusCollectionItem> busCollectionItems = busCollectionItemService.selectBusCollectionItemList(busCollectionItem);
        List<CollectItemWithDataVO> res = new ArrayList<>();
        for (BusCollectionItem item : busCollectionItems) {
            CollectItemWithDataVO collectItemWithDataVO = new CollectItemWithDataVO();
            BeanUtils.copyProperties(item, collectItemWithDataVO);
            collectItemWithDataVO.setCollectedDatas(collectedDataService.selectCollectDataByCollectItemId(item.getCollectionItemId(), size));
            res.add(collectItemWithDataVO);
        }

        busCollectionItem.setType("1");
        busCollectionItems = busCollectionItemService.selectBusCollectionItemList(busCollectionItem);
        for (BusCollectionItem item : busCollectionItems) {
            CollectItemWithDataVO collectItemWithDataVO = new CollectItemWithDataVO();
            BeanUtils.copyProperties(item, collectItemWithDataVO);
            List<RecordFile> recordFiles = recordFileService.selectRecordFileByCollectItemId(item.getCollectionItemId());
            if (recordFiles != null && !recordFiles.isEmpty()) {
                collectItemWithDataVO.setRecordFile(recordFiles.get(0));
            }
            res.add(collectItemWithDataVO);
        }

        busCollectionItem.setType("2");
        busCollectionItems = busCollectionItemService.selectBusCollectionItemList(busCollectionItem);
        for (BusCollectionItem item : busCollectionItems) {
            CollectItemWithDataVO collectItemWithDataVO = new CollectItemWithDataVO();
            BeanUtils.copyProperties(item, collectItemWithDataVO);
            collectItemWithDataVO.setCollectedDatas(collectedDataService.selectCollectDataByCollectItemId(item.getCollectionItemId(), size));
            res.add(collectItemWithDataVO);
        }

        return AjaxResult.success(res);
    }

    private String getCustomPath(VideoChannels videoChannels, String collectItemId) {
        return CUSTOM_PATH_PREV + collectItemId;
    }

    /**
     * 暂时没用到
     * @param recordInfo
     * @return
     */
    @PostMapping("onFinishRecordMp4")
    public AjaxResult onFinishRecordMp4(@RequestBody FinishRecordInfo recordInfo) {

        String file_path = recordInfo.getFile_path();
        RecordFile recordFile = new RecordFile();
        recordFile.setVideopath(file_path);
        List<RecordFile> recordFiles = recordFileService.selectRecordFileList(recordFile);
        if (recordFiles.size() == 0) {
            System.out.println("未发现相关联的视频");
        }
        if (recordFiles.size() > 1) {
            System.out.println("查询结果超出");
        }
        if (recordFiles.size() == 1) {
            System.out.println("绑定关联项");
            RecordFile recordFile1 = recordFiles.get(0);
            String[] split = file_path.split("/");
            // 根据命名规则未倒数第二个字符串
            String collectItemIdStr = split[split.length - 2];
            String collectItemId = collectItemIdStr.replaceAll("CollectItemId", "");
            recordFile.setCollectitemid(collectItemId);
            recordFileService.updateRecordFile(recordFile);
        }
        return AjaxResult.success();

    }
}
